#ifndef Server_h__
#define Server_h__

#include "NonCopyable.h"
#include "Singleton.h"
#include "MsgRecv.h"
#include "GameMessage.h"
#include "Networking.h"
#include "GameMessageQueue.h"
#include <map>

//frwrd dcl
class AcceptConnectionThread; 

//typedefs
typedef std::vector<Networking::Socket*> vSockets;
typedef std::map<int,Networking::Socket*> IDMap;
typedef std::map<int, MsgRecv*> mMsgRecvs;

class Server : public NonCopyable
{
private:
	Server();
	friend class Singleton<Server>;
public:
    void StartUp(int port);
    void ShutDown();
    void SetIDs();
    IDMap& GetIDs(){return m_clients;}
    void UpdateTimes();
    void Update();
    void ManageClients();
    void AddClient(Networking::Socket* client);
    void RemoveClient(int id);
    bool PingClient(int id);
    bool IsOpen(){return m_open;}
    int GetTimeStamp(){return m_timeStamp;}
    void AddMessageToQueue(GameMessage* gm);
    unsigned int GetNumberOfClients() {return m_clients.size();}
    void SetIP(char* ip);
	void SendToAllClients(GameMessage& gm);
    bool SendToClient(GameMessage& gm, int ID);
    std::string* GetIP(){return &m_ipAddr;}
private:
    //Add a vector of Connection Threads
    //Add a thread safe message queue
    IDMap    m_clients;
    int m_idGenerator;
    int m_timeStamp;
    int m_gameTickCounter;
    bool m_open;
    AcceptConnectionThread* m_acThread;
    mMsgRecvs m_msgRecvThreads;
    GameMessageQueue m_messageQueue;
    std::string m_ipAddr;
};

bool RecvGM(Networking::SockMsg& sm);
bool AddGm(Networking::SockMsg& sm);
bool SendGM(GameMessage& gm, Networking::Socket* sock);

typedef Singleton<Server>  TheServer;
#endif // Server_h__